package com.cloud.pole.common.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public abstract class DateUtils {
	
	public static final String DEFAULT_PATTERN = "yyyyMMddHHmmss";
	                                              
	public static String getSystemDate() {
		return formatDate(getSysDateTime(), DEFAULT_PATTERN);
	}
	
	public static String formatDate(Date date, String pattern){
		DateFormat df = new SimpleDateFormat(pattern);
		return df.format(date);
	}
	
	public static Date parseDate(String dateStr, String pattern){
		DateFormat df = new SimpleDateFormat(pattern);
		try {
			return df.parse(dateStr);
		} catch (ParseException e) {
			throw new RuntimeException("Error while parse date", e);
		}
	}
	
	public static Date getSysDateTime(){
		return new Date();
	}
	
	public static Date getSysDate(){
		return getDate(getSysDateTime());
	}
	
	public static Date getDate(Date date){
		if (date == null) return null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		
		return cal.getTime();
	}
	
	public static Date add(Date date, int dateField, int mount){
		if (date == null) return null;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(dateField, mount);
		
		return cal.getTime();
	}
	
	public static int getYear(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.YEAR);
	}
	
	public static int getMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MONTH)+1;
	}
	
	public static int getDayOfMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_MONTH);
	}
	
	/**
	 * Sunday=1
	 * SATURDAY=7
	 * @param date
	 * @return
	 */
	public static int getDayOfWeek(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_WEEK);
	}
	
	public static int getDayOfYear(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.DAY_OF_YEAR);
		
	}
	
	public static int getHour(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.HOUR_OF_DAY);
	}
	
	public static int getMinute(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MINUTE);
	}
	
	public static int getSecond(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.SECOND);
	}
	
	public static int getMillSecond(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		return cal.get(Calendar.MILLISECOND);
	}
	
	public static Timestamp getTimestamp(Date date){
		return new Timestamp(date.getTime());
	}
	
	public static java.sql.Date getSqlDate(Date date){
		return new java.sql.Date(date.getTime());
	}
	
	/**
	 * 根据时间戳返回Date
	 * @param timestamp
	 * @return
	 */
	public static Date getDateByTimeStamp(Long timestamp){
		Date date = new Date();
		date.setTime(timestamp);
		return date;
	}

	public static Date getDate(int year, int month, int day){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, day);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		
		return cal.getTime();
	}
	
	public static Date getDate(int year, int month, int day, int hour, int min, int second){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, day);
		cal.set(Calendar.HOUR_OF_DAY, hour);
		cal.set(Calendar.MINUTE, min);
		cal.set(Calendar.SECOND, second);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}
	
	
	public static Date getFirstDateOfMonth(int year, int month){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		
		return cal.getTime();
	}
	
	public static Date getLastDateOfMonth(int year, int month){
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month-1);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		
		return cal.getTime();
	}
	
	public static Date getPreviousDate(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)-1);
		return cal.getTime();
	}
	
	public static Date getNextDate(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH)+1);
		return cal.getTime();
	}
	
	public static Date getFirstDateOfMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH);
		return getFirstDateOfMonth(year, month);
	}
	
	public static Date getLastDateOfMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH);
		return getLastDateOfMonth(year, month);
	}
	
	/**
	 * 获得给定日期当周的WeekDay
	 * @param date
	 * @param weekOfDay		星期一是1，星期天是7
	 * @return
	 */
	public static Date getWeekDate(Date date, int weekOfDay){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		if (weekOfDay < 7){
			cal.set(Calendar.DAY_OF_WEEK, weekOfDay+1);
		}else{
			cal.set(Calendar.DAY_OF_WEEK, weekOfDay);//星期六
			cal.add(Calendar.DATE, weekOfDay-6);//往后推一天到周日
		}
		return cal.getTime();
	}
	
	/**
	 * 两个时间相差毫秒数
	 * @param start
	 * @param end
	 * @return
	 */
	public static Long minusMilliseconds(Date start, Date end,boolean ifswap){
		if (start.after(end) && ifswap==true){//交换
			Date tmp = start;
			start = end;
			end = tmp;
		}
		
		return end.getTime()-start.getTime();
	}
	
	public static Long minusSeconds(Date start, Date end,boolean ifswap){
		
		return minusMilliseconds(start, end,ifswap)/1000;
	}
	
	public static Long minusMinutes(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/(1000*60);
	}
	
	public static Long minusHours(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/(1000*60*60);
	}
	
	public static Long minusDay(Date start, Date end, boolean ifswap){
		return minusMilliseconds(start, end,ifswap)/(1000*60*60*24);
	}
	
	//排除天数只计算小时部分
	public static Long minusHoursExceptDay(Date start, Date end,boolean ifswap){
		return minusMilliseconds(start, end,ifswap)%(1000*60*60*24)/(1000*60);
	}
	
	//排除天数只计算分钟部分
	public static Long minusDayExceptHuors(Date start, Date end,boolean ifswap){

		return minusMilliseconds(start, end,ifswap)%(1000*60*60)/(1000*60);
	}
	
	//返回天小时分字符串
	public static String getIntervalDayHourMinStr(Date start, Date end,String []unitdes,boolean ifswap){
		long days=minusSeconds(start, end,ifswap)/(60*60*24);//得到总天数
		long hours=minusHoursExceptDay(start, end,ifswap)/60;//得到最后一天小时数
		long minus=minusDayExceptHuors(start, end,ifswap);//得到最后一小时分钟数
		String rtStr=days+unitdes[0]+hours+unitdes[1]+minus+unitdes[2];
		return rtStr;
	}
	
	/** 
	 * @param args 
	 */  
	public static Calendar getUtCCalendar() {  
	    //1、取得本地时间：    
	    final java.util.Calendar cal = java.util.Calendar.getInstance();   
	    System.out.println(cal.getTime());  
	    //2、取得时间偏移量：    
	    final int zoneOffset = cal.get(java.util.Calendar.ZONE_OFFSET);   
	    System.out.println(zoneOffset);  
	    //3、取得夏令时差：    
	    final int dstOffset = cal.get(java.util.Calendar.DST_OFFSET);    
	    System.out.println(dstOffset);  
	    //4、从本地时间里扣除这些差量，即可以取得UTC时间：    
	    cal.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));    
	   return cal;
	}
	/*
	 * 根据生日计算年龄	
	 */
	public static int getAge(Date birthDay){
		int age = 0;
		try{
			Calendar cal = Calendar.getInstance();
			if(birthDay == null || cal.before(birthDay)){
				System.err.println("DateUtils::getAge - birthDay is null or birthDay data error!");
			}
			else{
				int yearNow = cal.get(Calendar.YEAR);
				int monthNow = cal.get(Calendar.MONTH);
				int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
				cal.setTime(birthDay);

				int yearBirth = cal.get(Calendar.YEAR);
				int monthBirth = cal.get(Calendar.MONTH);
				int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
				age = yearNow - yearBirth;
				if (monthNow <= monthBirth) {
					if (monthNow == monthBirth) {
						if (dayOfMonthNow < dayOfMonthBirth)
							age--;
					} 
					else {
						age--;
					}
				}
			}
		}
		catch(Exception ex){
			age = 0;
			ex.printStackTrace();
		}
		return age;
	}
	/**
	 * 验证是否正确的时间格式
	 * @param strDate
	 * @param pattern
	 * @return
	 */
	public static boolean isValidDate(String strDate, String pattern) 
	{
	    boolean convertSuccess=true;
	    // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
	    SimpleDateFormat format = new SimpleDateFormat(pattern);
	    try {
	    	// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
	         format.setLenient(false);
	         format.parse(strDate);
	     } catch (ParseException e) {
	         // e.printStackTrace();
	         convertSuccess=false;
	     }
	     return convertSuccess;
	}
	/**
	 * 比较时间大小，0：相等 1：大于 -1：小于
	 * @param strBeginDate
	 * @param strEndDate
	 * @param pattern
	 * @return
	 */
	public static int compareDate(String strBeginDate, String strEndDate, String pattern) {
        DateFormat df = new SimpleDateFormat(pattern);
        try {
            Date dt1 = df.parse(strBeginDate);
            Date dt2 = df.parse(strEndDate);
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }
	
	public static void main(String[] args){
		Date date = new Date();
		Long l = Long.parseLong("1536296400000");
		date.setTime(l);
		System.out.println(DateUtils.formatDate(date, DateUtils.DEFAULT_PATTERN));
		System.out.println(DateUtils.isValidDate("20190909", "yyyyMMdd"));
	}
}
